// Copyright 2017 Baidu Inc. All Rights Reserved.
// Author: Chen Xihao (chenxihao@baidu.com)
//
// Description: Base class of Media

#include "baidu_media_base.h"

namespace duer {

enum {
    IDLE,
    PLAYING,
    PAUSE,
    RECORDING,
    STOPPING,
};


///// media with record use different lock 

rtos::Mutex MediaBase::_s_lock;
rtos::Mutex MediaBase::_s_record_lock;

int MediaBase::_s_status = IDLE;

int MediaBase::start_play(MediaType type) {
    int rs = 0;
    _s_lock.lock(osWaitForever);
    if (_s_status != PLAYING) {
        _s_status = PLAYING;
        rs = on_start_play(type);
    }
    _s_lock.unlock();
    return rs;
}

int MediaBase::write(const void* data, size_t size) {
    int rs = 0;
    _s_lock.lock(osWaitForever);
    if (_s_status == PLAYING || _s_status == PAUSE) {
        rs = on_write(data, size);
        if (data == NULL || size == 0) {
            _s_status = STOPPING;
        } else {
            _s_status = PLAYING;
        }
    }
    _s_lock.unlock();
    return rs;
}

int MediaBase::regulate_voice(unsigned char vol) {
    int rs = 0;
	///add 
	if(_s_status == RECORDING) 
	{
		printf("error regulate_voice in recording state\n");
		return rs;
	}
	
	
    _s_lock.lock(osWaitForever);
    rs = on_voice(vol);
    _s_lock.unlock();
    return rs;
}

int MediaBase::pause_play() {
    int rs = 0;
    _s_lock.lock(osWaitForever);
    if (_s_status == PLAYING) {
        rs = on_pause_play();
        _s_status = PAUSE;
    }
    _s_lock.unlock();
    return rs;
}

int MediaBase::stop_play() {
    int rs = 0;

	///// 
	
    _s_lock.lock(osWaitForever);
	if (_s_status == PLAYING || _s_status == PAUSE || _s_status == STOPPING) {
        rs = on_stop_play();
        _s_status = IDLE;
    }
    _s_lock.unlock();
    return rs;
}

int MediaBase::start_record() {
    int rs = 0;
    _s_record_lock.lock(osWaitForever);
    rs = on_start_record();
    _s_record_lock.unlock();
    return rs;
}


int MediaBase::start_record_amr()
{
	int rs = 0;
    _s_record_lock.lock(osWaitForever);
    rs = on_start_record_amr();
    _s_record_lock.unlock();
	return rs;
}

int MediaBase::stop_record_amr()
{
	int rs = 0;
    _s_record_lock.lock(osWaitForever);
    rs = on_stop_record_amr();
    _s_record_lock.unlock();
	return rs;

}

size_t MediaBase::read_amr(void* data, size_t size) {
    size_t rs = 0;
    _s_record_lock.lock(osWaitForever);
    rs = on_read_amr(data, size);
    _s_record_lock.unlock();	
    return rs;
}


size_t MediaBase::read(void* data, size_t size) {
    size_t rs = 0;
    _s_record_lock.lock(osWaitForever);
    rs = on_read(data, size);
    _s_record_lock.unlock();	
    return rs;
}


size_t MediaBase::read_done() 
{
    size_t rs = 0;
	_s_record_lock.lock(osWaitForever);	
    rs = on_read_done();	
    _s_record_lock.unlock();
    return rs;
}


size_t MediaBase::setBtMode()
{
	size_t rs = 0;
	_s_lock.lock(osWaitForever);
	rs = on_setBtMode();
	_s_lock.unlock();
	return rs;
}

size_t MediaBase::setUartMode()
{
	size_t rs = 0;
	_s_lock.lock(osWaitForever);
	rs = on_setUartMode();
	_s_lock.unlock();
	return rs;
}


int MediaBase::stop_record() {
    int rs = 0;
    _s_record_lock.lock(osWaitForever);
    rs = on_stop_record();
    _s_record_lock.unlock();
    return rs;
}

size_t MediaBase::SetName(const unsigned char* name)
{
	size_t rs = 0;
	_s_lock.lock(osWaitForever);
	rs = on_SetName(name);
	_s_lock.unlock();
	return rs;	
}


bool MediaBase::is_play_stopped() {
    bool rs = true;
    _s_lock.lock(osWaitForever);
    if (_s_status == PLAYING || _s_status == PAUSE) {
        rs = false;
    } else if (_s_status == STOPPING) {
        rs = is_play_stopped_internal();
        if (rs) {
            _s_status = IDLE;
        }
    } else {
        // do nothing
    }
    _s_lock.unlock();

    return rs;
}

} // namespace duer
